---新手引导
---是否开启引导
local ENABLE_GUIDE = Config.ENABLE_GUIDE
---@class GuideMgr
GuideMgr = { }
local this = GuideMgr
this.GuideDone = {}
local guideCfgList = {}
local BeginGuide = false
local NowGuide = nil    --当前引导步骤
---@type GComponent
local TouchBtn = nil    --当前引导的控件按钮
local isRootTouchBtn = false
local touchBtnNeedUpdatePos = false
local touchBtnPos = Vector2.New(0,0)
local MainTriggerID
local NowGuideTriggerID  --当前触发组id
local NowGuideID
local isGuiding = false

local pathCacheList = {}
local tempBtn = nil

GuideMgr.TriggerType = {
    level = 1,
    dungeonPass = 2,
    dungeonFailed = 3,
    rename = 4,
    expeditionFailed = 5,
    RepeatFailed = 6,
    FirstLogin = 7,
    stoneToTower = 8,
    expToExpedition = 9,
    petFirstGet = 10,
    guildUnlock = 11,
    potentialUnlock = 12,
    FirstOpenUI = 13,
}
GuideMgr.PauseType = {
    Pause = 1,
    RewardPause = 2,
    StoryPause = 3,
    battleResultPause = 4,
    favorPause=5,
}
GuideMgr.OPERATE_PARAM3 = {
    sortHeroId = 1,
    city = 2,
    wait = 3,
    longTouch = 4,
    sortMinLevel = 5,
    sortHighQuality = 6,
    alwaysLevelUp = 7,
    widgetSize = 8,
}
GuideMgr.OPERATE_PARAM2 = {
    drag = 1,
    formationAdjust = 2,
}

---@private
function GuideMgr.Init()
    this.pauseList = {}
    this.needSendIdList = {}
    this.softGuideList = {}
    this.curSoftData = {
        id = 0,
        maxDelayTime = 0,
        time = -1,
        isGuiding = false,
        ui = nil,
        btn = nil,
        parentView = "",
        oldParentView = "",
        guideDoneList = {},
        effGo = nil,
        ---@type GGraph
        dLoad = nil,
        effWrap = nil,
        updateCheckTime = 0,
        btnX = 0,
        btnY = 0,
        btnOffX = 0,
        btnOffY = 0,
    }
    this.clickData = {enable = false,interval = 0.3,time = 0.3}
    this.softGuidMapId = 0
    this.waitingMsgId = 0
    --软引导id,次数
    this.softGuideSavedMapId = GetPlayerPrefs("softGuideTipMapId") or 0
    local temp = decodeJsonStrToTabel(GetPlayerPrefs("softGuideTipIdCount") or {})
    this.SoftGuideSavedList = temp
end
function GuideMgr.OnCreate()
    this.isStartCheck = true
    MainTriggerID = 0
    table.clear(guideCfgList)
    this.AddTrigger(this.TriggerType.level)
    this.AddTrigger(this.TriggerType.dungeonPass,logicMgr.MapManager.getMapId())
    this.AddTrigger(this.TriggerType.rename)
    this.AddTrigger(this.TriggerType.FirstLogin)
    this.AddSoftGuideTrigger()
    this.LoadLocal()
    ListenEvent(Config.EventType.GuidePosMoveDone,this.GuidePosMoveDoneMsg)
    ListenEvent(Config.EventType.GuideFindHeroIdSuc,this.GuideFindHeroIdSucMsg)
    ListenEvent(Config.EventType.GuideNetReconnect,this.GuideNetReconnectSucMsg)
    --ListenEvent(Config.EventType.ShowUI,this.ShowUIMsg)
end
function GuideMgr.OnDestroy()
    this.isStartCheck = false
    NowGuide = nil
    BeginGuide = false
    tempBtn = nil
    if this.updateTimer ~= nil then
        utimer.remove(this.updateTimer)
    end
    this.updateTimer = nil
    this.needSendIdList = {}
    guideCfgList = {}
    this.DestroySoft()
    this.curSoftData = nil
    this.GuideDone = {}
    CloseEvent(Config.EventType.GuidePosMoveDone,this.GuidePosMoveDoneMsg)
    CloseEvent(Config.EventType.GuideFindHeroIdSuc,this.GuideFindHeroIdSucMsg)
    CloseEvent(Config.EventType.GuideNetReconnect,this.GuideNetReconnectSucMsg)
    --CloseEvent(Config.EventType.ShowUI,this.ShowUIMsg)
end
function GuideMgr.DestroySoft()
    if not this.curSoftData then
        return
    end
    if  not HelperFunc.IsNull(this.curSoftData.ui) then
        if not HelperFunc.IsNull(this.curSoftData.effGo) then
            destroy(this.curSoftData.effGo)
        end
        this.curSoftData.ui:Dispose()
    end
    this.curSoftData.id = 0
    this.curSoftData.ui = nil
    this.curSoftData.effGo = nil
    this.curSoftData.dLoad = nil
    this.curSoftData.effWrap = nil
    this.curSoftData.parentView = ""
end
function GuideMgr.AddSoftGuideTrigger()
    table.clear(this.softGuideList)
    local cfg = dataTable.getDataTable("t_guideweak")
    for k,v in pairs(cfg) do
        if v.f_TypeId > 0 then
            table.insert(this.softGuideList,v)
        end
    end
    --this.CheckSoftGuide()
end
function GuideMgr.SetSoftGuideMapId(mapId)
    this.softGuidMapId = mapId
end
function GuideMgr.IsSoftGuideDone(id)
    local done = this.curSoftData.guideDoneList[id]
    return done and done > 0
end
function GuideMgr.BattleStart()
    this.DestroySoft()
    this.CheckSoftGuide()
end
function GuideMgr.CheckSoftGuide()
    if not this.curSoftData or this.curSoftData.id > 0 then
        return
    end

    local mapId = this.softGuidMapId
    for k,v in pairs(this.softGuideList) do
        if not v.f_SectionTB then
            v.f_SectionTB = decodeJsonStrToTabel(v.f_Section)
        end

        local id = v.f_GuideWeakStepId
        local TipId = this.softGuideSavedMapId
        local TipCount = this.SoftGuideSavedList[tostring(id)] or 0
        local flag = true
        if mapId ~= tonumber(TipId) then
            TipCount = 0
        elseif tonumber(TipCount) >= v.f_Number then
            flag = false
        end
        if v.f_TypeId == 3 and logicMgr.VipManager.getVipLevel() >= 2 then--二倍速
            flag = false
        end
        if flag then
            local parent = this.FindChild(v.f_OperateParm)
            if parent ~= nil then
                for key, value in pairs(v.f_SectionTB) do
                    if mapId >= value[1] and mapId <= value[2] then
                        this.SoftGuideSavedList[tostring(id)] = tonumber(TipCount)
                        this.SetSoftGuideData(v)
                        return
                    end
                end
            end
        end
    end
    this.curSoftData.id = 0
end
function GuideMgr.SetSoftGuideData(cfg)
    if cfg == nil then return end
    this.curSoftData.isGuiding = false
    this.curSoftData.id = cfg.f_GuideWeakStepId
    this.curSoftData.time = cfg.f_Delayed
    this.curSoftData.maxDelayTime = cfg.f_Delayed
    this.curSoftData.parentView = this.GetView(cfg.f_OperateParm)
    if not HelperFunc.IsNull(this.curSoftData.ui) then
        this.curSoftData.ui.visible = false
    end
end

function GuideMgr.UpdateSoftGuide(dt)
    if this.curSoftData == nil then return end
    local data = this.curSoftData
    if this.curSoftData.updateCheckTime >= 1 then
        this.CheckSoftGuide()
        this.curSoftData.updateCheckTime = 0
    else
        this.curSoftData.updateCheckTime = this.curSoftData.updateCheckTime + dt
    end

    if isGuiding or this.isSoftPause or this.curSoftData.id == 0 then
        if this.curSoftData.isGuiding and not HelperFunc.IsNull(this.curSoftData.ui) then
            this.curSoftData.isGuiding = false
            this.curSoftData.ui.visible = false
        end
        return
    end
    if not this.curSoftData or this.curSoftData.isGuiding then
        if not HelperFunc.IsNull(data.btn) and not HelperFunc.IsNull(data.ui) then
            local x = data.btn.x
            local y = data.btn.y
            if math.abs(x-data.btnX)> 0.01 or math.abs(y -data.btnY) > 0.01 then
                data.btnX = x
                data.btnY = y
                data.ui:SetXY(x + data.btnOffX,y + data.btnOffY)
            end
        end
        return
    end
    local obj = GRoot.inst:GetChild(this.curSoftData.parentView)
    if obj == nil then
        this.DestroySoft()
        return
    end
    if obj == nil or not obj.visible then
        return
    end
    if this.curSoftData.time > 0 then
        this.curSoftData.time = this.curSoftData.time - dt
        return
    end
    local cfg = dataTable.getDataTableByStringId("t_guideweak",this.curSoftData.id)
    local parent = this.FindChild(cfg.f_OperateParm)
    if parent == nil then
        return
    end
    AddUIPackage("FUI/UIRookieGuide")
    local ui = this.curSoftData.ui
    if HelperFunc.IsNull(ui) then
        ui = newGComponent("MoveOn","UIRookieGuide" )
        this.curSoftData.ui = ui
        this.curSoftData.ui:GetChild("n5").visible = false

        resMgr:LoadPrefab("UIEff/UI_guide_arrowup", function(obj)
            if HelperFunc.IsNull(this.curSoftData.ui) then
                return
            end
            if this.curSoftData.dLoad then
                destroy(this.curSoftData.effGo)
                this.curSoftData.dLoad:Dispose()
            end
            local holder = GGraph.New();
            this.curSoftData.dLoad = holder
            holder:SetSize(10, 10);
            this.curSoftData.ui:AddChild(holder)
            holder:SetXY(100,50)
            this.curSoftData.effWrap = GoWrapper.New()
            local go = newObject(obj)
            --go:AddComponent(TCanvas)
            --go:AddComponent(TChangeSortingOrder)
            Util.SetOrderType(go,"Default");
            this.curSoftData.effWrap:SetWrapTarget(go,false)
            this.curSoftData.dLoad:SetNativeObject(this.curSoftData.effWrap);
            Util.Lua_SetLocalPositionXYZ(go.transform,0,0,0)
            this.curSoftData.effGo = go
        end);

    end
    this.curSoftData.btn = parent
    this.curSoftData.ui.visible = true
    this.curSoftData.ui.touchable = false
    obj:AddChild(ui)
    parent.onClick:Add(this.ClickSoftGuideBtn)
    local x = parent.width/2-ui.width/2
    local y = parent.height/2-ui.height/2

    if not string.IsNilOrEmpty(cfg.f_ArrowShift) then
        local pos = decodeJsonStrToTabel(cfg.f_ArrowShift)
        x = x + pos[1]
        y = y + pos[2]
    end
    this.curSoftData.btnOffX = x
    this.curSoftData.btnOffY = y
    this.curSoftData.btnX = parent.x
    this.curSoftData.btnY = parent.y
    this.curSoftData.ui:SetXY(parent.x + x,parent.y + y)
    this.curSoftData.isGuiding = true
    this.curSoftData.oldParentView = this.curSoftData.parentView
end
function GuideMgr.ClickSoftGuideBtn()
    --print("ClickSoftGuideBtn")
    if not this.curSoftData or HelperFunc.IsNull(this.curSoftData.ui) then
        return
    end
    local id = this.curSoftData.id
    this.curSoftData.ui.parent.onClick:Remove(this.ClickSoftGuideBtn)
    local cfg = dataTable.getDataTableByStringId("t_guideweak",id)
    this.curSoftData.guideDoneList[id] = 1
    local count = this.SoftGuideSavedList[tostring(id)] or 0
    this.SoftGuideSavedList[tostring(id)] = count + 1
    this.softGuideSavedMapId = this.softGuidMapId
    SetPlayerPrefs("softGuideTipMapId",this.softGuideSavedMapId)
    SetPlayerPrefs("softGuideTipIdCount",getJsonStr(this.SoftGuideSavedList))
    if cfg and cfg.f_NextStep > 0 then
        this.SetSoftGuideData(dataTable.getDataTableByStringId("t_guideweak",cfg.f_NextStep))
    else
        --[[local count = this.SoftGuideSavedList[tostring(id)] or 0
        this.SoftGuideSavedList[tostring(id)] = count + 1
        this.softGuideSavedMapId = this.softGuidMapId
        SetPlayerPrefs("softGuideTipMapId",this.softGuideSavedMapId)
        SetPlayerPrefs("softGuideTipIdCount",getJsonStr(this.SoftGuideSavedList))]]
        this.curSoftData.id = 0
    end
end
function GuideMgr.AddTrigger(type,param,isFirst,isDebug,forceUpdate)
    local tempguide = G.dataTable["t_guidetrigger"]
    for i, v in pairs(tempguide) do
        local flag = true
        local p = tonumber(v.f_TriggerParm)
        if v.f_TriggerType == type then
            if type == this.TriggerType.level then
                flag = p >= logicMgr.HeroManager.GetRoleLevel()
                if v.f_GuideGroupId == 1 and logicMgr.MapManager.getMapId() > 0 then
                    flag = false
                    this.SetTriggerDone(v.f_GuideGroupId,0)
                end
            end
            if type == this.TriggerType.dungeonFailed then
                flag = p > param and this.IsPreGroupTriggerDone(v.f_GuideGroupId)
            elseif type == this.TriggerType.expeditionFailed then
                flag = true
            elseif type == this.TriggerType.RepeatFailed then
                flag = (p > param) and this.IsPreGroupTriggerDone(v.f_GuideGroupId)
                if flag then
                    this.GuideDone[v.f_GuideGroupId] = nil
                end
            elseif type == this.TriggerType.dungeonPass then
                flag = p <= param and param < p + 1 or isDebug
                if p < param and this.GetTriggerDone(v.f_GuideGroupId) ~= 0 and not isDebug then --加个保护，已过的引导不再引导
                    --this.SendReqGuide(v.f_GuideGroupId,0)
                    this.SetTriggerDone(v.f_GuideGroupId,0)
                end
            elseif type == this.TriggerType.FirstLogin then
                flag = this.IsPreGroupTriggerDone(v.f_GuideGroupId) and not this.GetTriggerDone(tonumber(v.f_TriggerParm))
                if not this.GetTriggerDone(tonumber(v.f_TriggerParm)) then --后置引导未完成，开启改引导
                    this.SetTriggerDone(v.f_GuideGroupId,nil)
                end
            elseif type == this.TriggerType.stoneToTower or type == this.TriggerType.expToExpedition then
                flag = false
                local mapId = logicMgr.MapManager.getMapId()
                if mapId >= v.f_TriggerParm[1] and mapId < v.f_TriggerParm[2] then
                    flag = true
                end
            elseif type == this.TriggerType.FirstOpenUI then
                flag = v.f_TriggerPannel == param and this.IsPreGroupTriggerDone(v.f_GuideGroupId);
            end
            if flag and this.GetTriggerDone(v.f_GuideGroupId) ~= 0 then
                if not table.contains(guideCfgList,v.f_GuideGroupId) then
                    table.insert(guideCfgList, v.f_GuideGroupId);
                end
            end
        end

    end
    table.sort(guideCfgList,GuideMgr.GuideTriggerSort);
    if forceUpdate then
        this.CheckGuide(true)
    end
end
function GuideMgr.GuideTriggerSort(a,b)
    local aCfg = this.GetGuideTriggerCfg(a)
    local bCfg = this.GetGuideTriggerCfg(b)
    local aw = aCfg.f_TriggerType == this.TriggerType.FirstLogin and 0 or 10
    local bw = bCfg.f_TriggerType == this.TriggerType.FirstLogin and 0 or 10
    if aw ~= bw then
        return aw < bw
    end
    return aCfg.f_GuideGroupId < bCfg.f_GuideGroupId
end
function GuideMgr.InitGuideDone(triggerId,doneId)
    this.GuideDone[triggerId]= doneId
end
function GuideMgr.GetTriggerDone(triggerId)
    if triggerId == nil then return false end
    return this.GuideDone[triggerId]
end
function GuideMgr.IsPreGroupTriggerDone(triggerId)
    if triggerId == nil or triggerId == 0 then return false end
    local cfg = this.GetGuideTriggerCfg(triggerId)
    if not cfg then return true end
    if cfg.f_PrevGroup == 0 then
        return true
    end
    return this.GetTriggerDone(cfg.f_PrevGroup)
end
function GuideMgr.SetTriggerDone(triggerId,stepId)
    this.GuideDone[triggerId] = stepId
end

function GuideMgr.Pause(type)
    if not this.isStartCheck then return end
    if not type then type = this.PauseType.Pause end
    this.pauseList[type] = true
    this.DoPause()
end

function GuideMgr.Resume(type)
    if not this.isStartCheck then return end
    if not type then type = this.PauseType.Pause end
    this.pauseList[type] = nil
    this.DoResume()
end

function GuideMgr.SoftPause()
    this.isSoftPause = true
end
function GuideMgr.SoftResume()
    this.isSoftPause = false
end
function GuideMgr.IsPause()
    for k,v in pairs(this.pauseList) do
        return true
    end
    return false
end
---@private
function GuideMgr.DoPause()
    if not ENABLE_GUIDE then return end
    FireEvent(Config.EventType.GuidePause,true)
    this.HighlightObj(false)
end
---@private
function GuideMgr.DoResume()
    if not ENABLE_GUIDE then return end
    if this.IsPause() then return end
    FireEvent(Config.EventType.GuidePause,false)
    this.HighlightObj(true)
    this.InitGuideStep()
end

function GuideMgr.CheckGuide(needUpdate)
    if not ENABLE_GUIDE then return end
    if not this.isStartCheck then return end
    if needUpdate then
        this.Update()
    end
    if this.updateTimer ~= nil then
        return
    end
    this.updateTimer = utimer.timeCall(this.Update,66,-1)
end
function GuideMgr.LoadLocal()
    local value = Util.GetPlayerPrefs(logicMgr.HeroManager.GetRoleId().."gmguideclose")
    if value == nil or value == "1" then
        ENABLE_GUIDE = ENABLE_GUIDE and true
        this.CheckGuide()
    else
        this.HighlightObj(false)
        ENABLE_GUIDE = false
        isGuiding = false
        this.OnDestroy()
        closeUI(PanelNames.UIRookieGuide)
    end
end
function GuideMgr.LoadDebug(id)

    Util.SetPlayerPrefs(logicMgr.HeroManager.GetRoleId().."gmguideclose",1)
    ENABLE_GUIDE = true
    local cfg = dataTable.getDataTable("t_guidetrigger")
    for k,v in pairs(cfg) do
        if k ~= id then
            this.InitGuideDone(k,0)
        end
    end
    table.clear(this.pauseList)
    this.HighlightObj(false)
    FireEvent(Config.EventType.GuideForceEnd)

    this.OnCreate()
    BeginGuide = false
    NowGuide = nil
    TouchBtn = nil
    MainTriggerID = id
    this.CheckGuide()
    this.InitGuideDone(id,nil)
    this.AddTrigger(this.TriggerType.dungeonPass,logicMgr.MapManager.getMapId(),true,true)
end
function GuideMgr.GetNowGuideCfg()
    return NowGuide
end
function GuideMgr.Update()
    local dt = 0.066
    this.InitGuideStep()
    this.CheckUpdatePos()
    this.UpdateSoftGuide(dt)
    local data = this.clickData
    if not data.enable then
        data.time = data.time - dt
        if data.time < 0 then
            data.enable = true
            return
        end
    end
end
function GuideMgr.EnableClick()
    return this.clickData.enable
end
function GuideMgr.ResetClick(fixTime)
    this.clickData.enable = false
    this.clickData.time = fixTime or this.clickData.interval
end
function GuideMgr.CheckUpdatePos()
    if TouchBtn and touchBtnNeedUpdatePos then
        local x = TouchBtn.x
        local y = TouchBtn.y
        -- if math.abs(x - touchBtnPos.x) > 0.01 or math.abs(y - touchBtnPos.y) > 0.01 then
        --     touchBtnPos:Set(x,y)
        FireEvent(Config.EventType.GuideUpdatePos)
        --end
    end
end
function GuideMgr.ClickTouchButton(evt)

    if TouchBtn == nil then
        --logTrace("ClickTouchButton TouchBtn is nil")
        return
    end

    local old = TouchBtn
    if Util.IsGButton(old) then
        --logTrace("ClickTouchButton G TouchBtn name"..TouchBtn.name)
        old:FireClick(false,true);
    else
        --logTrace("ClickTouchButton N TouchBtn name"..TouchBtn.name)
        if old.name == "EquipBtn" then
            UICharactorInfoHero.onClickEquip()
        else
            old.onClick:Call(evt)
        end

    end
    old.onTouchBegin:Call(evt)
    old.onTouchEnd:Call(evt)

end
function GuideMgr.TouchBeginEffect()
    if TouchBtn == nil then return end
    if Util.IsGButton(TouchBtn) then
        TouchBtn:FireDownEffect()
    end
end
function GuideMgr.TouchEndEffect()
    if TouchBtn == nil then return end
    if Util.IsGButton(TouchBtn) then
        TouchBtn:FireUpEffect()
    end
end
function GuideMgr.touchBegin(evt)
    if TouchBtn == nil then return end
    TouchBtn.onTouchBegin:Call(evt)
end
function GuideMgr.touchEnd(evt)
    if TouchBtn == nil then return end
    TouchBtn.onTouchEnd:Call(evt)

end

function GuideMgr.InitGuideStep()
    if this.IsPause() then return end
    if (BeginGuide == true) then
        if (NowGuide.f_GuideType == 0 and NowGuide.f_OperateType == 1) then
            if (TouchBtn == nil or TouchBtn.visible == false) then
                BeginGuide = false;
                isGuiding = false
                this.forceEnd();
            end
        end
        if (NowGuide.f_OperateType == 0) then
            if (NowGuide.f_OperateParm ~= "") then
                if (TouchBtn == nil or TouchBtn.visible == false) then
                    BeginGuide = false;
                    isGuiding = false
                    this.forceEnd();
                end
            end
        end
        return
    end
    local tempMainGuideDownID = this.GetTriggerDone(MainTriggerID) --主线强引导
    if (tempMainGuideDownID == nil) then
        local SendTri = this.GetGuideTriggerCfg(MainTriggerID)
        if SendTri then
            local SendGuide = this.GetGuideCfg(SendTri.f_StartStep)
            this.pickGuide(SendTri, SendGuide)
        end
    else
        if (tempMainGuideDownID ~= 0) then --做完了就不继续了
            local SendTri = this.GetGuideTriggerCfg(MainTriggerID)
            local preSendGuide = this.GetGuideCfg(tempMainGuideDownID)
            if (preSendGuide.f_NextStep > 1 ) then
                local SendGuide = this.GetGuideCfg(preSendGuide.f_NextStep)
                this.pickGuide(SendTri, SendGuide)
            end
        else
            local SendTri = this.GetGuideTriggerCfg(MainTriggerID)
            if SendTri then
                if table.contains(guideCfgList,SendTri.f_NextGroup) then
                    MainTriggerID = SendTri.f_NextGroup
                    this.InitGuideStep()
                    return
                end
            end
        end
    end
    if (BeginGuide == true) then
        return
    end
    for k,id in pairs(guideCfgList) do
        --弱引导和 强引导同时进行 可以提前触发
        local SendTri = this.GetGuideTriggerCfg(id)
        local tempGuideDownID = logicMgr.GuideMgr.GetTriggerDone(id)
        local PreviewID = logicMgr.GuideMgr.GetTriggerDone(SendTri.f_PrevGroup)
        if (SendTri.f_PrevGroup == 0 or PreviewID == 0) then
            --如果弱引导前置做完了继续
            if (tempGuideDownID == nil) then
                local SendGuide = GuideMgr.GetGuideCfg(SendTri.f_StartStep)
                this.pickGuide(SendTri, SendGuide)
            else
                if (tempGuideDownID ~= 0) then
                    --如果做完了就不继续了
                    local preSendGuide = GuideMgr.GetGuideCfg(tempGuideDownID)
                    if (preSendGuide.f_NextStep > 1) then
                        local SendGuide = GuideMgr.GetGuideCfg(preSendGuide.f_NextStep)
                        this.pickGuide(SendTri, SendGuide)
                    end
                end
            end
        end
    end

end
function GuideMgr.pickGuide(sendTrriger, sendGuide)
    if (sendTrriger == nil or sendGuide == nil) then
        return ;
    end
    if sendTrriger.f_TriggerStageType > 0 and sendTrriger.f_TriggerStageType ~= logicMgr.BattlePlaybackManager.GetFightType() then
        return
    end
    if (sendTrriger.f_TriggerType == 1) then
        --如果是判断等级条件的
        if (logicMgr.HeroManager.GetRoleInfo().level >= tonumber(sendTrriger.f_TriggerParm)) then
            GuideMgr.EnterTrigger(sendGuide)
        end
    end
    if (sendTrriger.f_TriggerType == 2) then
        --如果是推关前置
        if (logicMgr.MapManager.getMapId() >= tonumber(sendTrriger.f_TriggerParm)) then
            this.CheckTriggerPanel(sendTrriger,sendGuide)
        end
    else
        this.CheckTriggerPanel(sendTrriger,sendGuide)
    end
end
function GuideMgr.CheckTriggerPanel(sendTrigger,sendGuide)
    if sendTrigger.f_TriggerPannel ~= "" then
        if(sendTrigger.f_StartStep == sendGuide.f_GuideStepId) then
            if this.FindChild(sendTrigger.f_TriggerPannel) then
                GuideMgr.EnterTrigger(sendGuide)
            end
        else
            GuideMgr.EnterTrigger(sendGuide)
        end
    else
        GuideMgr.EnterTrigger(sendGuide)
    end
end
function GuideMgr.DecodeCurOperateParam3()
    return this.DecodeOperateParam3(NowGuide)
end
function GuideMgr.DecodeOperateParam3(guideCfg)
    if not guideCfg then
        return nil
    end
    if string.IsNilOrEmpty(guideCfg.f_OperateParm3) then
        return nil
    end
    local tb = decodeJsonStrToTabel(guideCfg.f_OperateParm3)
    return tonumber(tb[1]),tonumber(tb[2]),tonumber(tb[3])
end
function GuideMgr.DecodeOperateParam2(guideCfg)
    if not guideCfg then
        return nil
    end
    if string.IsNilOrEmpty(guideCfg.f_OperateParm2) then
        return nil
    end
    local tb = decodeJsonStrToTabel(guideCfg.f_OperateParm2)
    return tonumber(tb[1]),tonumber(tb[2]),tonumber(tb[3])
end
function GuideMgr.DecodeCurOperateParam2()
    return this.DecodeOperateParam2(NowGuide)
end
--排序
function GuideMgr.IsNeedSortHero(type)
    return type == this.OPERATE_PARAM3.sortHeroId or type == this.OPERATE_PARAM3.sortMinLevel or type == this.OPERATE_PARAM3.sortHighQuality
end
--长按 点击
function GuideMgr.IsNeedTouch(type)
    return type == this.OPERATE_PARAM3.longTouch or type == this.OPERATE_PARAM3.alwaysLevelUp
end

function GuideMgr.FindOperate(guideCfg,priorityIndex)
    if guideCfg == nil then return nil end
    touchBtnNeedUpdatePos = false
    local type,heroId = this.DecodeOperateParam3(guideCfg)
    if this.IsNeedSortHero(type) then --1 指定英雄id ,5 英雄最低等级 6,英雄最高品质
        if tempBtn then
            touchBtnPos:Set(0,0)
            touchBtnNeedUpdatePos = true
            return tempBtn,false
        end
        if heroId and not logicMgr.HeroManager.HasOwnHeroByModelId(heroId) then
            logError("未获得该英雄"..tostring(heroId)..",跳过引导: "..tostring(this.GetGuideID()))
            this.EndCurGuide(guideCfg)
            return nil
        end
        FireEvent(Config.EventType.GuideFindHeroId,tostring(heroId),type)
        return nil
    else
        local _type = this.DecodeOperateParam2(guideCfg)
        if _type == this.OPERATE_PARAM2.formationAdjust then
            local tb = string_split(guideCfg.f_OperateParm,",")
            priorityIndex = priorityIndex or 1
            local child,flag,hasList = this.FindChild(tb[priorityIndex])
            if child and not flag then
                touchBtnNeedUpdatePos = true
                touchBtnPos:Set(child.x,child.y)
            end
            return child,flag
        else
            local child,flag,hasList = this.FindChild(guideCfg.f_OperateParm)
            if child and not flag then
                touchBtnNeedUpdatePos = true
                touchBtnPos:Set(child.x,child.y)
            end
            return child,flag
        end

    end
end

function GuideMgr.GetView(path)
    local tb = pathCacheList[path]
    if tb then
        return tb[1]
    end
    tb = string.split(path,"/")
    pathCacheList[path] = tb
    return tb[1]
end
function GuideMgr.FindChild(path)
    if string.IsNilOrEmpty(path) then return nil,false end

    local tb = pathCacheList[path]
    if not tb then
        tb = string.split(path,"/")
        pathCacheList[path] = tb
    end
    local index = 1
    ---@type GComponent
    local child
    local hasList = false
    while(true) do
        if index > #tb then break end
        if index == 1 then
            child = GRoot.inst:GetChild(tb[index])
            if child and child.visible == false then
                return nil,false
            end
        else
            if Util.IsGList(child) then
                local c = tonumber(tb[index])
                if c >= child.numChildren then
                    print("[引导]访问列表下标越界："..c..",path:"..path)
                    return nil,false
                end
                child = child:GetChildAt(c)
                hasList = true
            else
                child = child:GetChild(tb[index])
            end
        end
        if not child then
            if index ~= 1 then
                logError("[引导]找不到控件path:"..path)
            end
            return nil,false
        end
        index = index + 1
    end
    return child,#tb == 1,hasList
end
function GuideMgr.CheckOperateParam2(sendGuide)
    local _type = this.DecodeOperateParam2(sendGuide)
    if _type ~= this.OPERATE_PARAM2.formationAdjust then
        return false
    end
    local formation = logicMgr.FormationManager.GetFormation(EnumConst.FormationType.Duplicate)
    if formation[1] == "" or tonumber(formation[1])  == 0 then
        this.EnterTrigger(this.GetGuideCfg(sendGuide.f_NextStep))
        return true
    end
    if formation[2] == "" or tonumber(formation[2])  == 0 then
        this.EnterTrigger(this.GetGuideCfg(sendGuide.f_NextStep))
        return true
    end
    local hero1 = logicMgr.HeroManager.getHeroDatabyPartnerId(formation[1],true)
    local hero2 = logicMgr.HeroManager.getHeroDatabyPartnerId(formation[2],true)
    if not hero1 then
        logError("找不到阵型中的1号位英雄："..tostring(formation[1]))
        return true
    end
    if not hero2 then
        logError("找不到阵型中的2号位英雄："..tostring(formation[2]))
        return true
    end
    if hero1.level < hero2.level then
        local child,isRoot = this.FindOperate(sendGuide,1)
        this.DoBtnGuide(child,isRoot,sendGuide)
        return true
    else
        local child,isRoot = this.FindOperate(sendGuide,2)
        this.DoBtnGuide(child,isRoot,sendGuide)
        return true
    end
end
function GuideMgr.EnterTrigger(sendGuide)
    if (sendGuide.f_GuidePanel ~= "") then
        local index = string.find(sendGuide.f_GuidePanel,"/")
        if index then
            local name = string.sub(sendGuide.f_GuidePanel,index+1)
            local view = this.FindChild(name)
            if not view then
                showUI(sendGuide.f_GuidePanel);
                if sendGuide.f_GuidePanel == PanelNames.UIPlayerChangeName then
                    this.SetTriggerDone(NowGuideTriggerID,0)
                    this.forceEnd(true)
                    return
                end
            end
        end
    end
    if this.CheckOperateParam2(sendGuide) then
        return
    end
    if (sendGuide.f_OperateType == 1 or sendGuide.f_OperateType == 2) then

        local child,isRoot = this.FindOperate(sendGuide)
        if not child then return end
        this.DoBtnGuide(child,isRoot,sendGuide)
    end
    if (sendGuide.f_OperateType == 0) then
        local child
        if sendGuide.f_OperateParm ~= "" then
            child = this.FindOperate(sendGuide)
        end
        this.DoBtnGuide(child,false,sendGuide,true)
    end
end
function GuideMgr.DoBtnGuide(touchBtn,isRoot,guideCfg,isFullClick)
    TouchBtn = touchBtn
    if (TouchBtn == nil and not isFullClick) then
        return ;
    end
    NowGuideTriggerID = guideCfg.f_GuideGroupId;
    NowGuideID = guideCfg.f_GuideStepId;
    NowGuide = guideCfg;
    isRootTouchBtn = isRoot
    this.waitingMsgId = guideCfg.f_WaiteMassge or 0
    if this.waitingMsgId > 0 then
        NetMsgDecoder.RegisterResMessageCallback(this.waitingMsgId,this.ResMessageCallback)
    end
    if not isRoot then
        local delay = guideCfg.f_Delayed
        if delay < 0.3 then
            delay = 0.3
        end
        this.isLight = true
        utimer.delayCall(this.DelayShowHighlight,delay*1000)
    end
    isGuiding = true
    BeginGuide = true;
    log("[step]"..guideCfg.f_GuideStepId)
    -- 按钮点击
    local _guideDic = {}
    _guideDic.guide_step_id = tostring(NowGuideID)
    if isFullClick then
        _guideDic.trigger_type = "full_screen_click"
    else
        _guideDic.trigger_type = "button_click"
    end
    TAManager.TrackByDictionary("guide",_guideDic)
    this.CheckCityPos()
    this.CloseExtraUI()

    if isOpenUI(PanelNames.UIRookieGuide) then
        FireEvent(Config.EventType.GuideEnterTrigger)
    else
        showUI(PanelNames.UIRookieGuide)
    end
end
function GuideMgr.CloseExtraUI()
    local triggerCfg = this.GetGuideTriggerCfg(NowGuideTriggerID)
    if triggerCfg == nil then return end
    if triggerCfg.f_StartStep ~= NowGuideID then return end
    if triggerCfg.f_TriggerPannel ~= "UIBattle" then return end
    local createUIList = panelMgr:GetCreateUIList()
    for i = 0, createUIList.Length - 1 do
        local name = createUIList[i]
        if name ~= PanelNames.UIBattle and name ~= PanelResNames.UIScreenEffect
                and name ~= PanelResNames.UIHeadMenu and name ~= PanelNames.UIBottom
                and name ~= PanelNames.UIRookieGuide and name ~= PanelNames.UIFuncMenu
                and name ~= PanelResNames.UICover then
            closeUI(name)
        end
    end
    if not isOpenUI(PanelNames.UIBattle) then
        UIBottom.onSetBattle()
    end
end
function GuideMgr.DelayShowHighlight()
    if not this.isLight then return end
    this.HighlightObj(true)
end
function GuideMgr.CheckCityPos()
    if string.IsNilOrEmpty(NowGuide.f_OperateParm3) then
        return
    end
    local _OperateParm3 = decodeJsonStrToTabel(NowGuide.f_OperateParm3)
    if tonumber(_OperateParm3[1]) == 2 then
        FireEvent(Config.EventType.GuideCityUpdateAreaIndex,tonumber(_OperateParm3[2]))
    end
end
function GuideMgr.HighlightObj(isLight)
    this.isLight = isLight
    if NowGuide == nil or TouchBtn == nil then return end
    if isRootTouchBtn then return end
    if isLight and not this.IsGuiding() then
        return
    end
    if NowGuide.f_Ignore == 1 then
        return
    end
    local parent = TouchBtn.parent
    while(true) do
        if parent == "GRoot" or parent == nil then
            break
        end
        if parent.name == "UICharactorMain" then
            return
        end
        parent = parent.parent
    end
    local obj = TouchBtn.displayObject.gameObject
    if isLight then
        if obj and obj.name == "UIBottom" then
            --logError("[GuideMgr]已屏蔽")
            return
        end
        if obj then
            Util.SetOrderType(obj,"mapBeijing");
            local change = obj:AddComponent(TCanvasChangeLayer)
            change:SetLayer("mapBeijing")
        end
        if not string.IsNilOrEmpty(NowGuide.f_ExtraHighLight) then
            local _ExtraHighLight = decodeJsonStrToTabel(NowGuide.f_ExtraHighLight)
            for k,v in pairs(_ExtraHighLight) do
                local child = this.FindChild(v)
                if child then
                    local cobj = child.displayObject.gameObject
                    if cobj then
                        Util.SetOrderType(cobj,"mapBeijing");
                    end
                else
                    logError("[引导]找不到高亮路径："..v)
                end
            end
        end
    else
        if obj then
            Util.SetOrderType(obj,"Default");
            local change = obj:GetComponent(TCanvasChangeLayer)
            if change then
                change:SetLayer("Default")
                destroy(change)
            end
        end

        if not string.IsNilOrEmpty(NowGuide.f_ExtraHighLight) then
            for k,v in pairs(NowGuide.f_ExtraHighLight) do
                local child = this.FindChild(v)
                if child then
                    local cobj = child.displayObject.gameObject
                    if cobj then
                        Util.SetOrderType(cobj,"Default");
                    end
                end
            end
        end

    end
end
function GuideMgr.StartNextGuide()

    if NowGuide == nil then return end
    BeginGuide = false
    TouchBtn = nil
    tempBtn = nil
    --logTrace("StartNextGuide "..NowGuideID)
    this.SetTriggerDone(NowGuideTriggerID,NowGuideID)
    local cfg = this.GetGuideCfg(NowGuideID)
    if cfg and string.Contains(cfg.f_OperateParm,"UIBottom/TownBtn") then
        HelperFunc.ResetCityMode(1)
    end
    local _OperateParm3 = NowGuide.f_OperateParm3
    if _OperateParm3 and _OperateParm3[1] == 3 then --当前引导完后需要等待界面操作完成，
        this.forceEnd();
    end
    if (NowGuide.f_NextStep ~= 0) then
        --直接下一步
        this.SendReqGuide(NowGuideTriggerID,NowGuideID);
        local SendTri = dataTable.getDataTableById("t_guidetrigger",NowGuideTriggerID)
        local SendGuide = GuideMgr.GetGuideCfg(NowGuide.f_NextStep)
        this.pickGuide(SendTri, SendGuide);
    else
        this.SendReqGuide(NowGuideTriggerID,0);
        this.forceEnd();
        this.SetTriggerDone(NowGuideTriggerID,0)
        this.CheckRenameDone()
        isGuiding = false
        if (NowGuide.f_GuideType == 0) then
            this.forceEnd(true)
            --弱引导没有下一组
            NowGuide = nil;
            NowGuideID = 0;
            NowGuideTriggerID = 0;

        else
            local SendTri = this.GetGuideTriggerCfg(NowGuideTriggerID)
            if (SendTri.f_NextGroup ~= 0) then
                --如果下一组还有直接下一组的第一步
                if table.contains(guideCfgList,SendTri.f_NextGroup) then
                    MainTriggerID = SendTri.f_NextGroup
                    SendTri = this.GetGuideTriggerCfg(MainTriggerID)
                    local SendGuide = GuideMgr.GetGuideCfg(SendTri.f_StartStep)
                    this.pickGuide(SendTri, SendGuide);
                end
            end
        end
    end
    if this.IsPause() then
        this.DoPause()
    end
end


function GuideMgr.CheckRenameDone()
    local cfg = dataTable.getDataTable("t_guidetrigger")
    local curTrigger = cfg[NowGuideTriggerID]
    if curTrigger and curTrigger.f_TriggerType == this.TriggerType.rename then
        for k,v in pairs(cfg) do
            if k ~= NowGuideTriggerID and v.f_TriggerType == this.TriggerType.rename then
                this.SendReqGuide(k,0);
                this.SetTriggerDone(k,0)
            end
        end
    end
end
function GuideMgr.SkipThisTrigger()
    BeginGuide = false
    this.SetTriggerDone(NowGuideTriggerID,0)
    local SendTri = this.GetGuideTriggerCfg(NowGuideTriggerID)
    if (SendTri.f_NextGroup ~= 0) then
        --如果下一组还有直接下一组的第一步
        MainTriggerID = SendTri.f_NextGroup
        SendTri = this.GetGuideTriggerCfg(MainTriggerID)
        local SendGuide = this.GetGuideCfg(SendTri.f_StartStep)
        this.pickGuide(SendTri, SendGuide);
    end
end
function GuideMgr.forceEnd(sendMsg)
    FireEvent(Config.EventType.GuideForceEnd)
    this.HighlightObj(false)

    if sendMsg then
        this.SendReqGuide(NowGuideTriggerID,0)
    end
    TouchBtn = nil;
    tempBtn = nil
end
function GuideMgr.EndCurGuide(guideCfg)
    local _list = this.GetGuidingInStage(logicMgr.MapManager.getMapId())
    local triggerId = 0
    if guideCfg then
        triggerId = guideCfg.f_GuideGroupId
    end
    local find = false
    for k,v in pairs(_list) do
        if v == triggerId then
            find = true
        end
        this.SetTriggerDone(v,0)
        this.SendReqGuide(v,0)
    end
    if not find and triggerId ~= 0 then
        this.SetTriggerDone(triggerId,0)
        this.SendReqGuide(triggerId,0)
    end
    this.HighlightObj(false)
    FireEvent(Config.EventType.GuideForceEnd)
    TouchBtn = nil
    tempBtn = nil
    BeginGuide = false
    --弱引导没有下一组
    NowGuide = nil;
    NowGuideID = 0;
    NowGuideTriggerID = 0;
end
---startStage 开始关卡(包含)
---endStage 结束关卡(不包含)
function GuideMgr.HasGuidingInRankLevel(startStage,endStage)
    local cfg = dataTable.getDataTable("t_guidetrigger")
    for k,v in pairs(cfg) do
        if type(v.f_TriggerParm) == "string" then
            local stage = tonumber(v.f_TriggerParm)
            if stage and stage >= startStage and stage < endStage and this.GetTriggerDone(v.f_GuideGroupId) ~= 0 then
                return true
            end
        end
    end
    return false
end
---@param level number 关卡Id
---关卡完成后是否有引导
function GuideMgr.HasGuidingInStage(level)
    local cfg = dataTable.getDataTable("t_guidetrigger")
    for k,v in pairs(cfg) do
        if type(v.f_TriggerParm) == "string" then
            local stage = tonumber(v.f_TriggerParm)
            if stage == level and this.GetTriggerDone(v.f_GuideGroupId) ~= 0 then
                return true
            end
        end
    end
    return false
end
function GuideMgr.HasGuidingInCurStage(triggerId)
    local curStage = logicMgr.MapManager.getMapId()
    local cfg = dataTable.getDataTable("t_guidetrigger")
    for k,v in pairs(cfg) do
        if type(v.f_TriggerParm) == "string" then
            local stage = tonumber(v.f_TriggerParm)
            if v.f_GuideGroupId == triggerId then
                if stage == curStage and this.GetTriggerDone(v.f_GuideGroupId) ~= 0 then
                    return true
                else
                    return false
                end
            end
        end
    end
    return false
end
function GuideMgr.GetGuidingInStage(level)
    local cfg = dataTable.getDataTable("t_guidetrigger")
    local _list = {}
    for k,v in pairs(cfg) do
        if type(v.f_TriggerParm) == "string" then
            local stage = tonumber(v.f_TriggerParm)
            if stage and stage == level and this.GetTriggerDone(v.f_GuideGroupId) ~= 0 then
                table.insert(_list,v.f_GuideGroupId)
            end
        end
    end
    return _list
end
function GuideMgr.HasGuidingGotoBattle()
    local cfg = dataTable.getDataTable("t_guidetrigger")
    local mapId = logicMgr.MapManager.getMapId()
    for k,v in pairs(cfg) do
        if type(v.f_TriggerParm) == "string" then
            local stage = tonumber(v.f_TriggerParm)
            if stage == mapId and v.f_TriggerPannel == "UIBattle" and this.GetTriggerDone(v.f_GuideGroupId) ~= 0 and this.IsPreGroupTriggerDone(v.f_GuideGroupId) then
                local step = v.f_StartStep
                while(step ~= 0) do
                    local guidCfg = this.GetGuideCfg(step)
                    if guidCfg.f_OperateParm == "UIBattle/BossBtn" then
                        return true
                    end
                    step = guidCfg.f_NextStep
                end
                return false
            end
        end
    end
    return false
end
--有引导
function GuideMgr.IsGuiding(forceCheck)
    if forceCheck then
        this.CheckGuide(true)
    end
    return isGuiding
end

function GuideMgr.CheckInSoftGuid()
    if this.curSoftData then
        return this.curSoftData.isGuiding
    end
    return false
end

function GuideMgr.HasTouchButton()
    return TouchBtn ~= nil
end
function GuideMgr.GetButton()
    return TouchBtn
end
function GuideMgr.GetTouchBtnPos(root,w,h)
    local rootParent = root.parent
    if not TouchBtn then
        return 0,0
    end
    --local g = TouchBtn.gameObject:GetComponent("DisplayObjectInfo").displayObject.gOwner.asButton;
    local vec = Vector3.GetCacheVec()
    if TouchBtn.pivotAsAnchor then
        vec:Set(TouchBtn.x-TouchBtn.pivotX*TouchBtn.width, TouchBtn.y-TouchBtn.pivotY*TouchBtn.height)
    else
        vec:Set(TouchBtn.x,TouchBtn.y)
    end
    local parent = TouchBtn.parent
    if parent and parent.pivotAsAnchor then
        vec:Set(vec.x-parent.pivotX*parent.width,vec.y-parent.pivotY*parent.height)
    end
    --只处理居中
    if Util.IsGList(parent) and parent.align == 1 then
        vec:Set(vec.x+0.5*parent.width-TouchBtn.width/2,vec.y)
    end
    if root.pivotAsAnchor then
        vec:Set(vec.x+root.pivotX*w + (TouchBtn.width - w)/2, vec.y+root.pivotY*h + (TouchBtn.height - h)/2)
    else
        vec:Set(vec.x  + (TouchBtn.width - w)/2, vec.y + (TouchBtn.height - h)/2)
    end

    local x,y = ObjUtil.TransformPoint(parent,vec,rootParent)
    Vector3.ReturnToPool(vec)
    return x,y
end
function GuideMgr.GetBtnRootPos(root)
    local rootParent = root.parent
    if not TouchBtn then
        return 0,0
    end
    --local g = TouchBtn.gameObject:GetComponent("DisplayObjectInfo").displayObject.gOwner.asButton;
    local vec = Vector3.GetCacheVec()
    if TouchBtn.pivotAsAnchor then
        vec:Set(TouchBtn.x-TouchBtn.pivotX*TouchBtn.width, TouchBtn.y-TouchBtn.pivotY*TouchBtn.height)
    else
        vec:Set(TouchBtn.x,TouchBtn.y)
    end
    local parent = TouchBtn.parent
    if parent and parent.pivotAsAnchor then
        vec:Set(vec.x-parent.pivotX*parent.width,vec.y-parent.pivotY*parent.height)
    end
    local x,y = ObjUtil.TransformPoint(parent,vec,rootParent)
    Vector3.ReturnToPool(vec)
    return x,y
end
function GuideMgr.GetGuideTriggerCfg(id)
    return dataTable.getDataTableById("t_guidetrigger",id)
end
function GuideMgr.GetGuideCfg(id)
    local cfg = dataTable.getDataTableById("t_guide",id)
    if id > 0 and cfg == nil then
        logError("找不到配置表t_guide "..id)
    end
    return cfg
end
function GuideMgr.GetGuideID()
    return NowGuideID
end
function GuideMgr.GetGuideTrigger()
    return NowGuideTriggerID
end
function GuideMgr.GuidePosMoveDoneMsg()
    FireEvent(Config.EventType.GuideUpdatePos)
end
function GuideMgr.GuideFindHeroIdSucMsg(btn)
    if btn then
        log("GuideFindHeroIdSucMsg "..btn.name)
    end
    tempBtn = btn
    this.InitGuideStep()
end
function GuideMgr.SendReqGuide(sendTrigger,step)
    local cfg = this.GetGuideTriggerCfg(sendTrigger)
    if cfg and cfg.f_TriggerType == this.TriggerType.RepeatFailed then
        return
    end
    local s = this.needSendIdList[sendTrigger]
    if not s or step > s or step == 0 then
        this.needSendIdList[sendTrigger] = step
    end
    guideHandle.SendReqGuideMessage(sendTrigger,step)
end
function GuideMgr.ResGuideHandler(triggerId,step)
    local s = this.needSendIdList[triggerId]
    if s and ( step >= s or step == 0) then
        this.needSendIdList[triggerId] = nil
    else
        return
    end
end
function GuideMgr.GuideNetReconnectSucMsg(startReconnect)
    if startReconnect then return end
    for k,v in pairs(this.needSendIdList) do
        guideHandle.SendReqGuideMessage(k,v)
    end
end
function GuideMgr.ResMessageCallback(msg)
    if msg.msgId ~= this.waitingMsgId then
        return
    end
    log("[引导]消息接收:"..this.waitingMsgId)
    NetMsgDecoder.UnRegisterResMessageCallback(this.waitingMsgId,this.ResMessageCallback)
    this.waitingMsgId = 0
    this.ResetClick()
    FireEvent("GuideWaitingMsgCallback")
    this.StartNextGuide()
    if this.IsPause() then
        this.DoPause()
    end
end
function GuideMgr.WaitingMsgDone()
    if not this.IsGuiding() then
        return
    end
    if this.waitingMsgId > 0 then
        NetMsgDecoder.UnRegisterResMessageCallback(this.waitingMsgId,this.ResMessageCallback)
    end
    this.waitingMsgId = 0
end
function GuideMgr.GuideShowFullscreenMask()
    utimer.frameCall(this.DoGuideShowFullscreenMask,1)
end
function GuideMgr.DoGuideShowFullscreenMask()
    if not isOpenUI(PanelNames.UIRookieGuide) then
        showUI(PanelNames.UIRookieGuide)
    end
    FireEvent(Config.EventType.GuideShowFullscreenMask)
end
function GuideMgr.CheckUnlockGuiding(funcOpenType,triggerType)
    if logicMgr.FuncOpenManager.isOpen(funcOpenType) then
        local triggerId = 0
        for k,v in pairs(dataTable.getDataTable("t_guidetrigger")) do
            if v.f_TriggerType == triggerType then
                triggerId = v.f_GuideGroupId
                break
            end
        end
        if ENABLE_GUIDE and not this.HasGuidingInStage(logicMgr.MapManager.getMapId()) and not this.IsGuiding() and this.GetTriggerDone(triggerId) ~= 0 then
            this.AddTrigger(triggerType)
            return true
        end
    end
    return false
end
return GuideMgr